package com.fanrui.code.main;

import static io.netty.handler.codec.http.HttpHeaders.Names.CONNECTION;
import static io.netty.handler.codec.http.HttpHeaders.Names.CONTENT_LENGTH;
import static io.netty.handler.codec.http.HttpHeaders.Names.CONTENT_TYPE;
import static io.netty.handler.codec.http.HttpVersion.HTTP_1_1;

import java.io.InputStream;
import java.io.OutputStreamWriter;
import java.io.UnsupportedEncodingException;
import java.net.HttpURLConnection;
import java.net.URL;
import java.nio.charset.Charset;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Map.Entry;
import java.util.regex.Pattern;

import com.fanrui.code.mahjong.util.MahjongCardUtil;
import com.fanrui.code.message.PlayerSessions;
import com.google.gson.Gson;
import com.google.gson.JsonParser;

import io.netty.buffer.Unpooled;
import io.netty.channel.ChannelHandlerContext;
import io.netty.channel.ChannelInboundHandlerAdapter;
import io.netty.handler.codec.http.DefaultFullHttpResponse;
import io.netty.handler.codec.http.FullHttpResponse;
import io.netty.handler.codec.http.HttpHeaders;
import io.netty.handler.codec.http.HttpHeaders.Values;
import io.netty.handler.codec.http.HttpMethod;
import io.netty.handler.codec.http.HttpRequest;
import io.netty.handler.codec.http.HttpResponseStatus;
import io.netty.handler.codec.http.QueryStringDecoder;

@SuppressWarnings("deprecation")
public class HttpServerInboundHandler extends ChannelInboundHandlerAdapter {

	private String FLAG = "/server-opatrion/";
	private String PATTERNENDFLAG = ".*(?:\\?.*)?";
	private Pattern PATTERNFLAG = Pattern.compile(FLAG + PATTERNENDFLAG);
	private HttpRequest request;
	private boolean isGet;
	@SuppressWarnings("unused")
	private boolean isPost;

	/**
	 * POST: http://localhost:8844/dmap-sf/sendMsg?hello=df&world=women body: we
	 * are togather
	 * 
	 * GET: http://localhost:8844/dmap-sf/query?hello=df&world=women
	 */
	@Override
	public void channelRead(ChannelHandlerContext ctx, Object msg) throws Exception {
		String reslutStr = null;
		if (msg instanceof HttpRequest) {

			request = (HttpRequest) msg;

			String uri = request.getUri();
			HttpMethod method = request.getMethod();

			isGet = method.equals(HttpMethod.GET);
			isPost = method.equals(HttpMethod.POST);
			if (PATTERNFLAG.matcher(uri).matches()) {
				HttpRequerst hr = new HttpRequerst();
				hr.setMethod(getMethodStr(uri));
				if (isGet) {
					hr.setParameters(getParamerByNameFromGET());
				}
				reslutStr = handle(hr);
			}
		}
		if (reslutStr != null) {
			writeHttpResponse(reslutStr, ctx, HttpResponseStatus.OK);
		}
		// else {
		// writeHttpResponse("failure", ctx, HttpResponseStatus.OK);
		// }
	}

	@Override
	public void channelReadComplete(ChannelHandlerContext ctx) throws Exception {
		ctx.flush();
	}

	@Override
	public void exceptionCaught(ChannelHandlerContext ctx, Throwable cause) {
		ctx.close();
	}

	/**
	 * 获取uri中的方法
	 */
	private String getMethodStr(String uri) {
		return uri.substring(uri.indexOf(FLAG) + FLAG.length(), uri.indexOf("?"));
	}

	private void writeHttpResponse(String responseString, ChannelHandlerContext ctx, HttpResponseStatus status)
			throws UnsupportedEncodingException {
		FullHttpResponse response = new DefaultFullHttpResponse(HTTP_1_1, status,
				Unpooled.wrappedBuffer(responseString.getBytes(Charset.defaultCharset())));
		response.headers().set(CONTENT_TYPE, "text/plain");
		response.headers().add("Access-Control-Allow-Origin", "*");
		response.headers().set(CONTENT_LENGTH, response.content().readableBytes());
		if (HttpHeaders.isKeepAlive(request)) {
			response.headers().set(CONNECTION, Values.KEEP_ALIVE);
		}
		ctx.write(response);
		ctx.flush();
	}

	private Map<String, String> getParamerByNameFromGET() {
		QueryStringDecoder decoderQuery = new QueryStringDecoder(request.getUri());
		return getAllParameter(decoderQuery);
	}

	private Map<String, String> getAllParameter(QueryStringDecoder decoderQuery) {
		Map<String, String> result = new HashMap<String, String>();
		Map<String, List<String>> uriAttributes = decoderQuery.parameters();
		for (Entry<String, List<String>> attr : uriAttributes.entrySet()) {
			String key = attr.getKey();
			for (String attrVal : attr.getValue()) {
				result.put(key, attrVal);
			}
		}
		return result;
	}

	private String handle(HttpRequerst hr) {
		// 查询在线人数
		if ("queryOnlineNum".equals(hr.getMethond())) {
			return "{\"onLineNum\":" + new Gson().toJson(PlayerSessions.keySet()) + "}";
		}
		// 配牌
		if ("setCard".equals(hr.getMethond())) {
			String cards = hr.getParamter("val");
			MahjongCardUtil.modelCards = new JsonParser().parse(cards).getAsJsonArray();
			return "Success";
		}
		return "false";
	}

	public static String post(String strURL, String params) {
		try {
			URL url = new URL(strURL);// 创建连接
			HttpURLConnection connection = (HttpURLConnection) url.openConnection();
			connection.setDoOutput(true);
			connection.setDoInput(true);
			connection.setUseCaches(false);
			connection.setInstanceFollowRedirects(true);
			connection.setRequestMethod("POST");// 设置请求方式
			connection.setRequestProperty("Accept", "application/json");// 设置接收数据的格式
			connection.setRequestProperty("Content-Type", "application/json");// 设置发送数据的格式
			// connection.setRequestProperty("Content-Type","application/x-www-form-urlencoded;charset=utf-8");//
			// 设置发送数据的格式
			connection.connect();
			OutputStreamWriter out = new OutputStreamWriter(connection.getOutputStream(), "UTF-8");// utf-8编码
			out.append(params);
			out.flush();
			out.close(); // 读取响应
			int length = (int) connection.getContentLength();// 获取长度
			InputStream is = connection.getInputStream();
			if (length != -1) {
				byte[] data = new byte[length];
				byte[] temp = new byte[512];
				int readLen = 0;
				int destPos = 0;
				while ((readLen = is.read(temp)) > 0) {
					System.arraycopy(temp, 0, data, destPos, readLen);
					destPos += readLen;
				}
				String result = new String(data, "UTF-8");
				System.out.println(result);
				return result;
			}
		} catch (Exception e) {
			e.printStackTrace();
		}
		return "error";

	}

}
